Skip to content

fix(sdks/ts): don't crash on Node watch-mode messages - #4284

Merged
gregfurman merged 5 commits into
hatchet-dev:mainfrom
CarbonHQ:fix-heartbeat-worker-watch-mode-messages
Jul 27, 2026
Merged

fix(sdks/ts): don't crash on Node watch-mode messages#4284
gregfurman merged 5 commits into
hatchet-dev:mainfrom
CarbonHQ:fix-heartbeat-worker-watch-mode-messages

Conversation

@princed

@princed princed commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Description

Fixes a Node watch-mode compatibility issue in the TypeScript SDK heartbeat worker. Newer Node worker reload/watch behaviour can emit internal worker-thread messages such as watch:require and watch:import through the normal message event, see nodejs/node#62368.

The heartbeat controller previously assumed every worker message was a heartbeat log message and dynamically dispatched this.logger[message.type](message.message), which can fail for those internal messages.

For internal I used a much simpler fix via yarn patch, please let me know if that's something you prefer instead, happy to update the PR.

diff --git a/clients/dispatcher/heartbeat/heartbeat-controller.js b/clients/dispatcher/heartbeat/heartbeat-controller.js
index 246cb771d0beeb1d5ecaffb0c28bd5ebfb145c9e..32e9b0f6a4eff21649f27888d6374289a2727c3e 100644
--- a/clients/dispatcher/heartbeat/heartbeat-controller.js
+++ b/clients/dispatcher/heartbeat/heartbeat-controller.js
@@ -45,7 +45,7 @@ class Heartbeat {
                     },
                 });
                 this.heartbeatWorker.on('message', (message) => {
-                    this.logger[message.type](message.message);
+                    this.logger[message.type]?.(message.message);
                 });
             }
         });

Similar problem was also encounter in other projects, e.g. https://redirect.github.com/pinojs/thread-stream/pull/213

Type of change

  • Bug fix (non-breaking change which fixes an issue)

What's Changed

  • Added zod schema for heartbeat messages
  • Added runtime guard based on the schema

Checklist

Changes have been:

  • Tested (unit tests and manually)
  • Linted and formatted
  • Documented (where applicable)
  • Added to CHANGELOG (where applicable) -- see Keep a Changelog

Testing

  • Tested with AI-generated units test that were subsequently deleted to comply with the AI policy
  • Manually using yarn link in an affected project.

馃 AI Disclosure
  • I acknowledge that an LLM was used in the creation of this Pull Request, in accordance with Hatchet's AI_POLICY.md.
  • Details: AI-generated test were deleted to comply with the policy

@vercel

vercel Bot commented Jun 26, 2026

Copy link
Copy Markdown

@princed is attempting to deploy a commit to the Hatchet Team on Vercel.

A member of the Team first needs to authorize it.

@github-actions github-actions Bot added the sdk-ts Related to the Typescript SDK label Jun 26, 2026

@gregfurman gregfurman left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the neat fix! I'd love a small reproducer so I can compare this new behaviour locally. Feel free to even provide this output yourself within the PR body.

Also, could you include an entry for this in the sdks/typescript/CHANGELOG.md?

Once done, think this looks good to go 馃槃

@gregfurman

Copy link
Copy Markdown
Collaborator

馃憢 @princed. Are you still able to provide a reproducer?

@princed

princed commented Jul 15, 2026

Copy link
Copy Markdown
Contributor Author

Sorry @gregfurman, I haven't had time to prepare a full-fledged repro it a repo/gist, but actually you can follow these steps:

  1. Run any Node example using node --watch [script.js] with a Node version above 24.16.0
  2. Edit worker code while running
  3. Observe worker process crashing

Please let me know if you need more details. If you would like a working repro, can you point me at any example that be easily run?

@princed

princed commented Jul 21, 2026

Copy link
Copy Markdown
Contributor Author

Hey @gregfurman, I've just had a look, it seems to be a simple repro:

Steps

  1. Make sure Node version is 24.16.0 or above
  2. Run Hatchet dev server
  3. From Hatchet repo root go to cd /sdks/typescript
  4. Run
env TS_NODE_TRANSPILE_ONLY=true node --watch \
  -r ts-node/register \
  -r tsconfig-paths/register \
  src/v1/examples/quickstart/worker.ts
  1. Observe the error:
        this.logger[message.type](message.message);
                                 ^
TypeError: this.logger[message.type] is not a function
    at Worker.<anonymous> (<repo-root>/sdks/typescript/src/clients/dispatcher/heartbeat/heartbeat-controller.ts:45:34)
    at Worker.emit (node:events:509:28)
    at Worker.emit (node:domain:489:12)
    at MessagePort.<anonymous> (node:internal/worker:350:14)
    at MessagePort.[nodejs.internal.kHybridDispatch] (node:internal/event_target:843:20)
    at MessagePort.<anonymous> (node:internal/per_context/messageport:23:28)
Failed running 'src/v1/examples/quickstart/worker.ts'. Waiting for file changes before restarting...

I've also updated the changelog as requested.

@princed
princed requested a review from gregfurman July 21, 2026 07:07

@gregfurman gregfurman left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Was able to reproduce this with Node v24.18.0. Thanks for the neat contribution!

@gregfurman
gregfurman merged commit ac7040b into hatchet-dev:main Jul 27, 2026
15 of 16 checks passed
@princed

princed commented Jul 27, 2026

Copy link
Copy Markdown
Contributor Author

Awesome, thanks for merging!

@princed
princed deleted the fix-heartbeat-worker-watch-mode-messages branch July 27, 2026 12:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

sdk-ts Related to the Typescript SDK

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants